/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pe.com.procesos;

import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import jodd.mail.EmailUtil;
import jodd.mail.ReceivedEmail;
import pe.com.util.CorreoJSON;
import pe.com.util.CorreoJsonMeta;
import pe.com.util.FindAfile;

/**
 *
 * @author romulogalindo
 */
public class ProcesadorCorreo {

    Connection con;
    Statement st;
    List<File> files_backup;
    String path_backup = "/home/romulogalindo/correos";
    String path_backup_anhio = "2014";
//    FileSystemManager fsManager;

    public ProcesadorCorreo(String path_backup, String path_backup_anhio) {
        this.path_backup = path_backup;
        this.path_backup_anhio = path_backup_anhio;
        try {
            System.out.println("Iniciando constructor Agajo::" + con.isClosed());
        } catch (Exception ep) {
            System.out.println("ep:" + ep.getMessage());
        }
    }

    public void procesar(Connection con) {
        this.con = con;
        int a = 1;
        try {
            //Listar & conseguir todos los archivos tgz sobre y unicamente esa carpeta
            System.out.println("path_backup:" + path_backup + ", path_backup_anhio:" + path_backup_anhio);
            files_backup = findBackups(path_backup);
            System.out.println("Backups a procesar:" + files_backup.size());

            //Se procede a trabajar con cada archivo backup
            for (File backup : files_backup) {
                try {
                    //Ahora tenemos que sacar el nombre de la carpeta
                    String backup_name = getName(backup.getName());

                    if (backup_name.length() > 0) {
                        //Creamos la carpeta donde se depositara lo futuramente extraido
                        File backup_destino = getFileDestino(path_backup + "/" + backup_name);

                        //Extraemos el backup
                        extraerBackup("tar -xvf " + backup.getAbsolutePath() + " -C " + backup_destino.getAbsolutePath());

                        //Buscar todos los archivos eml para ser procesados
                        List<File> eml_files = conseguirEML(backup_destino);
                        System.out.println("============================================::" + eml_files.size());

                        for (File m_eml : eml_files) {

                            try {
                                //Leemos el eml.meta
                                CorreoJsonMeta correojsonmeta = getJsonMeta(m_eml.getAbsolutePath() + ".meta");

                                //Leemos el eml
                                ReceivedEmail mail = EmailUtil.parseEML(m_eml);

                                CorreoJSON correojson = new CorreoJSON();
                                correojson.setFe_correo(new SimpleDateFormat("dd/MM/yyyy").format(mail.getReceiveDate()));
                                correojson.setNo_remite(mail.getFrom());
                                correojson.setNo_asunto(mail.getSubject());
                                correojson.setNo_destto(Arrays.asList(mail.getTo()));
                                correojson.setNo_destcc(Arrays.asList(mail.getCc()));
                                correojson.setNo_destco(Arrays.asList(mail.getBcc()));
                                correojson.setId_coreml(correojsonmeta.getId());

                                path_backup_anhio = "" + new SimpleDateFormat("yyyy").format(mail.getReceiveDate());

                                String carpeta = m_eml.getParent().substring(path_backup.length() + 1, m_eml.getParent().length());
                                correojson.setNo_carpet(carpeta);
                                String json = new Gson().toJson(correojson);

                                String correo_sql = "select * from corhis.pbregistrar_correo_historico('" + backup_name + "','" + json + "');";

                                long id_correo = getCorreoId(correo_sql);
                                if (id_correo != 0) {
                                    File corX = new File(path_backup + "/" + path_backup_anhio + "/" + carpeta + "/");
                                    if (!corX.exists()) {
                                        corX.mkdirs();
//                                        System.out.println("Creando carpetas>" + corX.getAbsolutePath());
                                    }

//                                    System.out.println("de[" + m_eml.getAbsolutePath() + "] a[" + corX.getAbsolutePath() + "/" + id_correo + ".eml" + "]");
                                    m_eml.renameTo(new File(corX.getAbsolutePath() + "/" + id_correo + ".eml"));

//                                    System.out.println("de[" + m_eml.getAbsolutePath() + ".meta" + "] a[" + corX.getAbsolutePath() + "/" + id_correo + ".eml.meta" + "]");
                                    new File(m_eml.getAbsolutePath() + ".meta").renameTo(new File(corX.getAbsolutePath() + "/" + id_correo + ".eml.meta"));
                                    System.out.println("" + correo_sql);
                                } /*else {
                                 //                                    System.out.println("de:" + (m_eml.getAbsolutePath()) + " a:" + (path_backup + "/" + path_backup_anhio + "/" + backup_name + "/" + carpeta + a + ".eml"));
                                 m_eml.renameTo(new File(path_backup + "/" + path_backup_anhio + "/" + backup_name + "/" + carpeta + "/" + a + ".eml"));
                                 new File(m_eml.getAbsolutePath() + ".meta").renameTo(new File(path_backup + "/" + path_backup_anhio + "/" + backup_name + "/" + carpeta + a + ".eml.meta"));
                                 System.out.println("2::" + correo_sql);
                                 }*/

                                a++;
                            } catch (Exception ep) {
                                System.out.println("::::" + ep.getMessage());
                            }
                        }

                    } else {
                        System.out.println("NO hay archivo coherente para procesar");
                    }
                    //Ahora elminando el archivo padre
//                    backup.delete();
                } catch (Exception ep) {
                    System.out.println("[Agajo->Agajo()->for(backup)]" + ep.getMessage());
                }
            }
        } catch (Exception ep) {
            System.out.println("[Agajo-> Agajo()]" + ep.getMessage());
            ep.printStackTrace();
        }
    }

    public String getStringMeta(File file) {
        String json = "";
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(file.getAbsolutePath()), StandardCharsets.UTF_8)) {
            String line = null;
            while ((line = reader.readLine()) != null) {
                json = json + line;
            }
        } catch (Exception ep) {
        }
        return json;
    }

    public List<File> findBackups(String path) {
        File file_root = new File(path);
        File[] files = file_root.listFiles(new FileFilter() {
            @Override
            public boolean accept(File f) {
                if (!f.isDirectory()) {
                    if (f.getName().indexOf("tgz") > -1) {
                        System.out.println("Archivo base encontrado:" + f.getAbsolutePath());
                        return true;
                    }
                }
                return false;
            }
        });

        List<File> a = Arrays.asList(files);
        return a;
    }

    public String getName(String backup_name) {
        String r = "";
        if (backup_name.split("accesocrediticio.com").length == 2) {
            r = backup_name.split("accesocrediticio.com")[0] + "accesocrediticio.com";
        } else if (backup_name.split("acceso.com").length == 2) {
            r = backup_name.split("acceso.com")[1] + "acceso.com";
        }
        return r;
    }

    public File getFileDestino(String file_destino) {
        File f = new File(file_destino);
        if (!f.exists()) {
            f.mkdir();
        }
        return f;
    }

    private void extraerBackup(String exe) {
        System.out.println("[process]tar -xvf " + exe);
        try {
            Process pr = Runtime.getRuntime().exec(exe);
            int exitVal = pr.waitFor();
        } catch (Exception ep) {
        }
    }

    private List<File> conseguirEML(File backup_destino) {
        List<File> eml_files = null;
        try {
            FindAfile buscador = new FindAfile(".eml");
            Files.walkFileTree(Paths.get(backup_destino.getAbsolutePath()), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, buscador);
            eml_files = buscador.getListFiles();
        } catch (IOException ex) {
            eml_files = new ArrayList<>();
        }
        return eml_files;
    }

    private CorreoJsonMeta getJsonMeta(String eml) {
        File eml_meta = new File(eml);
        String json_meta = getStringMeta(eml_meta);
        return new Gson().fromJson(json_meta, CorreoJsonMeta.class);
    }

    private long getCorreoId(String correo_sql) {
        long id = 0;
        try {
//            System.out.println("::>::" + con.isClosed());
            st = con.createStatement();
            ResultSet rpta = st.executeQuery(correo_sql);
            while (rpta.next()) {
                id = rpta.getLong(1);
            }
        } catch (Exception ep) {
            id = 0;
            System.out.println("Error select:\n" + ep.getMessage());
            ep.printStackTrace();
        }
        return id;
    }

    public static void main(String[] args) {
        ProcesadorCorreo agajo = new ProcesadorCorreo("/home/romulogalindo/correos", "2014");
        agajo.procesar(null);
    }

}
